using AutoMapper;
using MediatR;
using RBAC.Domain.MaterialManage;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ERP.MaterialFile;
using System.Transactions;

namespace RBAC.Write.Api.Application.Handler.ERP.MaterialFile
{
    /// <summary>
    /// 更新物料分类处理类
    /// </summary>
    public class UpdateMaterTypeHandler : IRequestHandler<UpdateMaterTypeCommand, APIResult<bool>>
    {
        private readonly IBaseRepository<MaterType> materTypeRepository;
        private readonly ILogger<UpdateMaterTypeHandler> logger;
        private readonly IMapper mapper;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="materTypeRepository">物料分类仓储</param>
        /// <param name="logger">日志记录器</param>
        /// <param name="mapper">对象映射器</param>
        public UpdateMaterTypeHandler(
            IBaseRepository<MaterType> materTypeRepository,
            ILogger<UpdateMaterTypeHandler> logger,
            IMapper mapper)
        {
            this.materTypeRepository = materTypeRepository;
            this.logger = logger;
            this.mapper = mapper;
        }

        /// <summary>
        /// 处理更新物料分类请求
        /// </summary>
        /// <param name="request">更新物料分类请求</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>更新结果</returns>
        public async Task<APIResult<bool>> Handle(UpdateMaterTypeCommand request, CancellationToken cancellationToken)
        {
            APIResult<bool> result = new APIResult<bool>();

            try
            {
                logger.LogInformation("开始更新物料分类: {Id} - {TypeName}", request.Id, request.TypeName);

                // 1. 验证物料分类是否存在
                var existingMaterType = materTypeRepository.QueryFirstOrDefault<MaterType>(
                    "SELECT * FROM MaterType WHERE Id = @Id AND IsDeleted = false",
                    new { Id = request.Id });

                if (existingMaterType == null)
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "物料分类不存在";
                    logger.LogWarning("物料分类不存在: {Id}", request.Id);
                    return result;
                }

                // 2. 数据验证
                if (string.IsNullOrWhiteSpace(request.TypeCode))
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "分类编码不能为空";
                    logger.LogWarning("分类编码验证失败");
                    return result;
                }

                if (string.IsNullOrWhiteSpace(request.TypeName))
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "分类名称不能为空";
                    logger.LogWarning("分类名称验证失败");
                    return result;
                }

                if (request.TypeCode.Length > 50)
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "分类编码长度不能超过50个字符";
                    logger.LogWarning("分类编码长度验证失败: {Length}", request.TypeCode.Length);
                    return result;
                }

                if (request.TypeName.Length > 100)
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "分类名称长度不能超过100个字符";
                    logger.LogWarning("分类名称长度验证失败: {Length}", request.TypeName.Length);
                    return result;
                }

                // 3. 检查分类编码是否已存在（排除当前记录）
                var existingByCode = materTypeRepository.QueryFirstOrDefault<int>(
                    "SELECT COUNT(1) FROM MaterType WHERE TypeCode = @TypeCode AND Id != @Id AND IsDeleted = false",
                    new { TypeCode = request.TypeCode, request.Id });

                if (existingByCode > 0)
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "分类编码已存在";
                    logger.LogWarning("分类编码已存在: {TypeCode}", request.TypeCode);
                    return result;
                }

                // 4. 检查分类名称是否已存在（排除当前记录）
                var existingByName = materTypeRepository.QueryFirstOrDefault<int>(
                    "SELECT COUNT(1) FROM MaterType WHERE TypeName = @TypeName AND Id != @Id AND IsDeleted = false",
                    new { TypeName = request.TypeName, request.Id });

                if (existingByName > 0)
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "分类名称已存在";
                    logger.LogWarning("分类名称已存在: {TypeName}", request.TypeName);
                    return result;
                }

                // 5. 验证上级分类是否存在（如果有上级分类）
                if (request.ParentId.HasValue && request.ParentId.Value > 0)
                {
                    // 检查上级分类是否存在
                    var parentExists = materTypeRepository.QueryFirstOrDefault<int>(
                        "SELECT COUNT(1) FROM MaterType WHERE Id = @Id AND IsDeleted = false",
                        new { Id = request.ParentId.Value });

                    if (parentExists == 0)
                    {
                        result.Code = APIEnums.Error;
                        result.Msg = "指定的上级分类不存在";
                        logger.LogWarning("上级分类验证失败: {ParentId}", request.ParentId.Value);
                        return result;
                    }

                    // 检查是否尝试将自身设置为自己的上级
                    if (request.ParentId.Value == request.Id)
                    {
                        result.Code = APIEnums.Error;
                        result.Msg = "不能将自身设置为上级分类";
                        logger.LogWarning("尝试将自身设置为上级分类: {Id}", request.Id);
                        return result;
                    }
                }

                // 6. 更新物料分类实体
                var updateSql = @"
                    UPDATE MaterType 
                    SET TypeCode = @TypeCode, 
                        TypeName = @TypeName, 
                        Unit = @Unit, 
                        Status = @Status, 
                        Lenght = @Lenght, 
                        SupplyMode = @SupplyMode, 
                        ParentId = @ParentId
                    WHERE Id = @Id";

                var parameters = new
                {
                    request.Id,
                    request.TypeCode,
                    request.TypeName,
                    request.Unit,
                    request.Status,
                    request.Lenght,
                    request.SupplyMode,
                    request.ParentId
                };

                using (TransactionScope tran = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    try
                    {
                        // 7. 执行更新操作
                        var affectedRows = materTypeRepository.Execute(updateSql, parameters);

                        if (affectedRows <= 0)
                        {
                            throw new InvalidOperationException("物料分类更新失败，未找到要更新的记录");
                        }

                        tran.Complete();

                        result.Code = APIEnums.Success;
                        result.Data = true;
                        result.Msg = "物料分类更新成功";

                        logger.LogInformation("物料分类 {Id} - {TypeName} 更新完成，影响行数: {AffectedRows}",
                            request.Id, request.TypeName, affectedRows);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, "更新物料分类过程中发生错误: {Message}", ex.Message);
                        result.Code = APIEnums.Error;
                        result.Msg = "更新物料分类失败";
                        result.Data = false;
                        throw;
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "更新物料分类失败: {Message}", ex.Message);
                result.Code = APIEnums.Error;
                result.Msg = "更新物料分类失败";
                result.Data = false;
            }

            return result;
        }
    }
}